// src/utils/request.js
import axios from 'axios'
import { ElMessage, ElLoading } from 'element-plus'

const DEFAULT_CONFIG = {
  baseURL: "http://localhost:3000/api",
  timeout: 30000,
  headers: {
    'Content-Type': 'application/json;charset=UTF-8'
  }
}

const RETRY_CONFIG = {
  retries: 2,
  retryDelay: 1000,
  shouldRetry: (error) => !error.response
}

class HttpRequest {
  constructor() {
    this.instance = axios.create(DEFAULT_CONFIG)
    this.loadingInstance = null
    this.controllerMap = new Map()
    this.initInterceptors()
  }

  initInterceptors() {
    // 请求拦截
    this.instance.interceptors.request.use(
      (config) => {
        const controller = new AbortController()
        config.signal = controller.signal
        this.controllerMap.set(config.url, controller)

        const token = localStorage.getItem('token')
        if (token) {
          config.headers.Authorization = `Bearer ${token}`
        }

        if (config.showLoading !== false) {
          this.loadingInstance = ElLoading.service({
            lock: true,
            text: '加载中...',
            background: 'rgba(0, 0, 0, 0.5)'
          })
        }

        return config
      },
      error => Promise.reject(error)
    )

    // 响应拦截
    this.instance.interceptors.response.use(
      async (response) => {
        if (this.loadingInstance) {
          this.loadingInstance.close()
        }

        this.controllerMap.delete(response.config.url)

        const res = response.data

        if (res.code !== 200) {
          ElMessage.error(res.message || '请求错误')
          return Promise.reject(res)
        }

        return res
      },
      async (error) => {
        if (this.loadingInstance) {
          this.loadingInstance.close()
        }

        const status = error.response?.status
        let errorMessage = ''

        switch (status) {
          case 401:
            errorMessage = '登录已过期'
            localStorage.removeItem('token')
            window.location.href = '/login'
            break
          case 403:
            errorMessage = '没有权限'
            break
          case 404:
            errorMessage = '资源不存在'
            break
          case 500:
            errorMessage = '服务器错误'
            break
          default:
            errorMessage = error.message || '请求失败'
        }

        if (errorMessage && error.config.showError !== false) {
          ElMessage.error(errorMessage)
        }

        const config = error.config || {}
        if (RETRY_CONFIG.shouldRetry(error) && config.retryCount < RETRY_CONFIG.retries) {
          config.retryCount = config.retryCount || 0
          config.retryCount += 1

          await new Promise(resolve => 
            setTimeout(resolve, RETRY_CONFIG.retryDelay)
          )

          return this.instance(config)
        }

        return Promise.reject(error)
      }
    )
  }

  request(config) {
    return this.instance.request(config)
  }

  get(url, config) {
    return this.instance.get(url, config)
  }

  post(url, data, config) {
    return this.instance.post(url, data, config)
  }

  put(url, data, config) {
    return this.instance.put(url, data, config)
  }

  delete(url, config) {
    return this.instance.delete(url, config)
  }

  cancelRequest(url) {
    const controller = this.controllerMap.get(url)
    if (controller) {
      controller.abort()
      this.controllerMap.delete(url)
    }
  }

  cancelAllRequests() {
    this.controllerMap.forEach(controller => controller.abort())
    this.controllerMap.clear()
  }
}

const http = new HttpRequest()

export default http
